package svc.elib.socnet;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;

import svc.elib.db.Author;
import svc.elib.db.Paper;
import edu.uci.ics.jung.graph.UndirectedSparseGraph;

/**
 * Makes evolutionary snapshots
 * 
 * @author svc
 */
public class EvolutionarySnapshots {

	private Net net;
	private UndirectedSparseGraph<Author, Link> g;
	
	
	/**
	 * array of snapshots (per year)
	 */
	private Net[] snapshots;
	
	private int startYear;
	private int endYear;
	
	public EvolutionarySnapshots(Net net) {
		this.net = net;
		g = net.getGraph();
		determineTimeSpan();
		snapshots = new Net[endYear - startYear + 1];
		for (int i = 0; i < snapshots.length; i++) 
			snapshots[i] = new Net(net.getName() + "_" + (startYear + i));
		formSnapshots();
	}
	
	private void determineTimeSpan() {
		startYear = Integer.MAX_VALUE;
		endYear = Integer.MIN_VALUE;
		
		Collection<Author> aCol = g.getVertices();
		Iterator<Author> it = aCol.iterator();
		while (it.hasNext()) {
			Author a = it.next();
			int firstYear = a.getFirstYear();
			int lastYear = a.getLastYear();
			if (firstYear < startYear) {
				startYear = firstYear;
			}
			if (lastYear > endYear) {
				endYear = lastYear;
			}
		}
	}
	
	private void formSnapshots() {
		for (int i = 0; i < snapshots.length; i++) {
			int year = startYear + i;
			Net current = snapshots[i];
			
			Collection<Author> authorCol = g.getVertices();
			Iterator<Author> authorIt = authorCol.iterator();
			while (authorIt.hasNext()) {
				Author a = authorIt.next();
				int aYear = a.getFirstYear();
				if (aYear <= year) {
					current.createNode(a);
				}
			}
			
			Collection<Link> linkCol = g.getEdges();
			Iterator<Link> linkIt = linkCol.iterator();
			while (linkIt.hasNext()) {
				Link l = linkIt.next();
				int lYear = l.getFirstYear();
				if (lYear <= year) {
					Author src = l.getSrc();
					Author dst = l.getDst();
					LinkedList<Paper> pic = l.getPapersInCommon();
					LinkedList<Paper> picRestriction = new LinkedList<Paper>();
					for (int k = 0; k < pic.size(); k++) {
						if (pic.get(k).getYear() <= year) {
							picRestriction.add(pic.get(k));
						}
					}
					
					current.createLink(src, dst, picRestriction);
				}
			}
		}
	}
	
	public void info() {
		System.out.println("\nEvolution of " + net.getName());
		System.out.println("Start year = " + startYear + ", end year = " + endYear);
		for (int i = 0; i < snapshots.length; i++) {
			ConnectedComponents comp = new ConnectedComponents(snapshots[i]);
			comp.resolveComponents();
			System.out.println(snapshots[i].getName() + " -- " + (startYear + i) + 
							   ", #n = " + snapshots[i].getGraph().getVertexCount() + 
							   ", #l = " + snapshots[i].getGraph().getEdgeCount() +
							   ", #comp = " + comp.getNumComponents());
		}
	}
	
	public Net[] getSnapshots() {
		return snapshots;
	}
	
	public int getStartYear() {
		return startYear;
	}
	
	public int getEndYear() {
		return endYear;
	}
}
